<template>
  <vxe-grid ref='xGrid' v-bind="gridOptions"
    @checkbox-change="checkboxChange"
    @checkbox-all="checkboxAll"
    @checkbox-range-change="checkboxRangeChange">
      <template #form>
        <slot name="form"></slot>
      </template>

      <!-- left -->
      <template #toolbar_buttons>
        <slot name="topLeft1"></slot>
        <Divider type="vertical"/>
        <span v-for="(v, i) in buttons.topLeft" :key="`i-${i}`">
          <Popconfirm v-if="v.tip" placement="bottom"
            :disabled="batchDeleteDisabled"
            :title="v.tipContent"
            cancel-text="取消"
            @confirm="handleCall(v.func)">
            <template v-if="v.disable === 2" #icon><QuestionCircleOutlined style="color: red" /></template>
            <a v-if="v.disable === 2" :class="{disabled:batchDeleteDisabled}">{{v.name}}{{checkboxCount}}</a>
            <a v-else-if="v.disable === 1" :class="{disabled:oneDisabled}">{{v.name}}</a>
            <a v-else>{{v.name}}</a>
          </Popconfirm>
          <span v-else>
            <a v-if="v.disable > 0" :class="{disabled:oneDisabled}" @click="handleCall(v.func)">{{v.name}}</a>
            <a v-else @click="handleCall(v.func)">{{v.name}}</a>
          </span>
          <Divider type="vertical"/>
        </span>
        <slot name="topLeft2"></slot>
      </template>

      <!-- operate -->
      <template #operate="{ row }">
      <Divider type="vertical"/>
      <span v-for="(v, i) in buttons.inner" :key="`i-${i}`">
          <Popconfirm v-if="v.tip"
            placement="bottom"
            :title="v.tipContent"
            cancel-text="取消"
            @confirm="handleCall(v.func, row)">
            <a>{{v.name}}</a>
          </Popconfirm>
          <a v-else @click="handleCall(v.func, row)">{{v.name}}</a>
          <Divider type="vertical"/>
        </span>

      </template>

  </vxe-grid>
</template>
<script lang="ts" name="XGrid" setup>
import {reactive, ref, toRaw, computed, watchPostEffect,} from 'vue';
import {useRoute} from 'vue-router';
import {VxeTablePropTypes, VxeGridPropTypes, VxeGridProps,} from 'vxe-table';
import {Popconfirm, Divider} from 'ant-design-vue';
import { QuestionCircleOutlined } from '@ant-design/icons-vue';
import { defHttp } from '/@/utils/http/axios';
import { toLower } from 'lodash-es';
// import { usePermission } from '/@/hooks/web/usePermission';

// const { hasPermission } = usePermission();
const route = useRoute();
let prefix = '/' + toLower(route.name?.toString())

const buttons = reactive({
  topLeft: [] as any[],
  // topRight: [] as any [],
  inner: [] as any[],
})

const props = defineProps({
  url: { type: String, default: '' },
  size: { type: String, default: 'mini' },
  isTree: { type: Boolean, default: false },
  columns: { type: Array, default: () => [] },
  height: { type: Number, default: window.innerHeight - 113 },
  border: {type: [String, Boolean], default: 'full'}, // default | full | outer | inner | none
  line: {type: Boolean, default: true},
  stripe: {type: Boolean, default: true},
  showOverflow: {type: [String, Boolean], default: 'tooltip'}, // 'ellipsis' | 'title' | 'tooltip'
  notCheckbox: {type: Array<Number | String>, default: () => []},
  checkStrictly: {type: Boolean, default: false,},
  printTop: { type: String, default: '' },
  printBottom: { type: String, default: '' },
  printStyle: { type: String, default: '' },
})

const xGrid = ref()
const gridOptions = reactive<VxeGridProps>({
  border: props.border as VxeTablePropTypes.Border,
  resizable: true,
  showHeaderOverflow: true,
  showOverflow: props.showOverflow as VxeTablePropTypes.ShowOverflow,
  highlightHoverRow: true,
  keepSource: true,
  id: 'xGrid_' + new Date().getTime(),
  stripe: props.stripe,
  height: props.height,
  size: props.size as VxeTablePropTypes.Size,
  rowId: 'id',
  columns: props.columns as VxeGridPropTypes.Columns,
  // columns: insideColumns.data,
  columnConfig: {
    useKey: true,
    isCurrent: true,
    isHover: true,
  },
  rowConfig: {
    useKey: true,
    isCurrent: true,
    isHover: false,
    keyField: 'id',
  },
  customConfig: {
    storage: true,
  },
  tooltipConfig: {
  },
  printConfig: {
    sheetName: '',
    mode: 'selected',
    style: props.printStyle,
    modes: ['current', 'selected', 'all'],
    columnFilterMethod: ({ column, $columnIndex }) => {
      return column.type !== 'checkbox';
    },
    beforePrintMethod: ({ content, options }) => {
      let result = props.printTop + content + props.printBottom;
      // result = `<div style="width:100%">` + result + `</div>`
      return result;
    }
  },
  sortConfig: {
    trigger: 'cell',
    remote: false
  },
  filterConfig: {
    remote: false
  },
  pagerConfig: {
    total: 0,
    currentPage: 1,
    pageSize: 50,
    pageSizes: [50, 100, 200, 500, 1000],
    layouts: ['PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total'],
    border: true,
    background: true,
    perfect: true,
  },
  toolbarConfig: {
    // refresh: true,
    // import: false,
    // export: false,
    // print: false,
    // zoom: false,
    // custom: false,
    slots: {
      buttons: 'toolbar_buttons',
    },
  },
  exportConfig: {
    remote: false,
    types: ['xlsx'],
    modes: ['current', 'selected', 'all'],
  },
  checkboxConfig: {
    reserve: false,
    highlight: true,
    range: true,
    trigger: 'cell',
    checkStrictly: props.checkStrictly,
    checkMethod: ({row}) => {
      if (props.notCheckbox) {
        return !(props.notCheckbox.some((e:number) => e === row.id))
      }
      return true;
    },
  },
  proxyConfig: {
    ajax: {
      query({ page, sort, sorts, filters, form }) {
        batchDeleteDisabled.value = true
        return defHttp.get<any>({ url: url.value, params: page });
      },
      queryAll({ page, sort, sorts, filters, form }) {
        return defHttp.get<any>({ url: prefix + '/list', params: page });
      }
    }
  },
});

let {buttonList} = route.meta
if (buttonList) {
  buttons.topLeft = buttonList.filter(e => e.place === 0)
  buttons.inner = buttonList.filter(e => e.place === 2)

  let topRight = buttonList.filter(e => e.place === 1)
  topRight.forEach(e => {
    if (e.name === '刷新表') gridOptions!.toolbarConfig!.refresh = true;
    if (e.name === '导入') gridOptions!.toolbarConfig!.import = true;
    if (e.name === '导出') gridOptions!.toolbarConfig!.export = true;
    if (e.name === '打印') gridOptions!.toolbarConfig!.print = true;
    if (e.name === '最大化') gridOptions!.toolbarConfig!.zoom = true;
    if (e.name === '自定义列') gridOptions!.toolbarConfig!.custom = true;
  })
}

const url = computed(() => {
  let path = ''
  if (props.url) {
    path = props.url;
  } else {
    path = props.isTree ? (prefix + '/list') : (prefix + '/table');
  }
  return path;
})
watchPostEffect(() => {
  if (props.isTree) {
    gridOptions.treeConfig = {
      rowField: 'id',
      trigger: 'cell',
      line: props.line,
      expandAll: true,
    }
    gridOptions!.checkboxConfig!.range = false;
    delete gridOptions.pagerConfig
  }
})
const checkboxCount = ref(' (0)')
watchPostEffect(() => {
  if (xGrid.value) {
    checkboxCount.value = ` (${xGrid.value.getCheckboxRecords(true).length})`

    let innerLen = buttons.inner.length
    if (innerLen > 0 && props.columns.length > 0) {
      let opt = props.columns.filter((e:any) => e?.title === '操作')
      if (opt.length === 0) {
        let width = 70 * innerLen;
        xGrid.value.loadColumn([...props.columns, 
          {title: '操作', sortable: false, slots: {default: 'operate'}, width: width, align: 'center',}])
      }
    }
  }
})

const reload = () => {
  batchDeleteDisabled.value = true
  oneDisabled.value = true
  defHttp.get<any>({ url: url.value,}).then(dd => {
    if (props.isTree) {
      xGrid.value.reloadData(dd)
    } else {
      // xGrid.value.loadData(dd?.result)
      xGrid.value.reloadData(dd?.result)
      let {pager} = xGrid.value.getProxyInfo()
      pager.total = dd?.page?.total
    }
  })
}

const handleDelete = (...params: number[]) => {
  if (params.length > 0) {
    defHttp.delete({url: prefix, data: params}).then(() => {
      batchDeleteDisabled.value = true
      reload()
    })
  }
}
const handleBatchDelete = () => {
  let checkedList = xGrid.value.getCheckboxRecords(true).map((e:any) => e.id)
  handleDelete(...checkedList)
}

const batchDeleteDisabled = ref(true)
const oneDisabled = ref(true)
const checkedRowRef = ref()
function setCheckedRowRef (list:any[]) {
  if (list.length === 1) {
      checkedRowRef.value = toRaw(list[0])
      oneDisabled.value = false
  } else {
    checkedRowRef.value = null
    oneDisabled.value = true
  }
}
const checkboxChange = ({ checked, row, rowIndex, $rowIndex, column, columnIndex, $columnIndex, $event }) => {
  let checkedList = xGrid.value.getCheckboxRecords(true)
  setCheckedRowRef(checkedList)
  batchDeleteDisabled.value = !(checkedList.length > 0)
  emits('checked-count', checkedList.length)
}
const checkboxAll = ({ checked, $event }) => {
  setCheckedRowRef([])
  batchDeleteDisabled.value = !checked
  emits('checked-count', xGrid.value.getCheckboxRecords(true).length)
}
const checkboxRangeChange = ({ $event }) => {
  let checkedList = xGrid.value.getCheckboxRecords(true)
  setCheckedRowRef(checkedList)
  batchDeleteDisabled.value = !(checkedList.length > 0)
  emits('checked-count', checkedList.length)
}

const emits = defineEmits(['create', 'edit', 'copy', 'grant', 'checked-count', 'resetPassword']);
const funcMap: Map<String, Function> = new Map([
  ['create', () => emits('create')],
  ['edit', () => emits('edit', checkedRowRef.value)],
  // ['delete', () => handleDelete(checkedRowRef.value?.id)],
  ['batchDelete', handleBatchDelete],
  ['copy', () => emits('copy', checkedRowRef.value)],
  ['grant', () => emits('grant', checkedRowRef.value?.id)],
  ['resetPassword', () => emits('resetPassword', checkedRowRef.value)],
]);
// 调用
const handleCall = (funcName:string, row?:any) => {
  if (funcName !== '-') {
    let func = funcMap.get(funcName)
    if (func) {
      if(row) func(row)
      else func()
    }
  }
}

defineExpose({
  reload,
  setAllTreeExpand(expand:boolean) {
    xGrid.value.setAllTreeExpand(expand)
  },
  getCheckedList():any[] {
    return xGrid.value.getCheckboxRecords(true)
  },
  clearCheckboxRow() {
    xGrid.value.clearCheckboxRow()
  }
})
</script>
<style>
.disabled {
  pointer-events: none;
  opacity: .5;
  -moz-opacity: .5;
  /* 黑白色 */
  -webkit-filter: grayscale(100%); /* Chrome, Safari, Opera */
  filter: grayscale(100%);
}
.btn{
  font-weight: bold;
}
</style>
